<?php
/**
 * Created by PhpStorm.
 * User: yy
 * Date: 2019/5/15
 * Time: 14:58
 */

namespace app\common\service\environmentAnalysis;

use think\Db;
use think\facade\Config;
use app\common\service\CommonService;
use app\common\service\airquality\AirQualityStationAqiRealtimeDayService;

class EnvironmentAnalysisPollutantService
{
    /**
     * 获取污染物分析左上侧表格
     * @author yy by 2019/5/21
     * @param array $param
     * @return array
     * @throws \MongoDB\Driver\Exception\Exception
     */
    public function getTable($param = [])
    {
        $list               = [];
        $commonService      = new CommonService();
        $companyIdArr       = $commonService->getCompanyIdArr(1);
        $industry_limit_arr = $commonService->getIndustryLimitIdmysql();
        # step1 全市排放量计算
        $dayService = new AirQualityStationAqiRealtimeDayService();
        $days       = $dayService->diffDays($param['start_time'], $param['end_time']);
        # 模拟表(排除掉晋能长治热电有限公司)（不用判断时间）(SO2,NOX,烟尘)
        $data_simulate = Db::query("select sum(emissions_so2_total * $days) as emissions_so2, sum(emissions_nox_total * $days) as emissions_nox, sum(emissions_smoke_total * $days) as emissions_smoke,
avg(operation_concentration_so2) as operation_concentration_so2, avg(operation_concentration_nox) as operation_concentration_nox, avg(operation_concentration_smoke) as operation_concentration_smoke
                                from company_industry_monitor_simulation_day_avg
                                where company_id in $companyIdArr and industry_id in $industry_limit_arr");
        // 实时企业脱硫 && 脱硝排放量
        $param['company_pollutant_name'] = 'so2';
        $emission_so2                    = $commonService->getRealCompanyEmission($param, 1);
        $param['company_pollutant_name'] = 'nox';
        $emission_nox                    = $commonService->getRealCompanyEmission($param, 1);
        # 模拟表一定有值,脱硫脱硝表（晋能热电）不一定有
        $real_emissions_so2 = isset($emission_so2[0]['emissions']) ? $emission_so2[0]['emissions'] : 0;
        $real_emissions_nox = isset($emission_nox[0]['emissions']) ? $emission_nox[0]['emissions'] : 0;
        $list[0]            = ['name' => 'SO2', 'emissions' => $data_simulate[0]['emissions_so2'] + $real_emissions_so2];
        $list[1]            = ['name' => 'NOX', 'emissions' => $data_simulate[0]['emissions_nox'] + $real_emissions_nox];
        $list[2]            = ['name' => '烟尘', 'emissions' => $data_simulate[0]['emissions_smoke']];
        # step2 贡献企业排放总量计算
        # 查询有贡献的企业ID
        $ids_contribution = $this->getContributionCompanyIds($param);
        $id_arr           = trim(strtr(strtr($ids_contribution, '(', ' '), ')', ' '));
        $id_arr_new       = explode(',', $id_arr);
        if ($ids_contribution != '()') {
            // 模拟表中贡献企业的排放量
            $data_simulate = Db::query("select sum(emissions_so2_total * $days) as emissions_so2, sum(emissions_nox_total * $days) as emissions_nox, sum(emissions_smoke_total * $days) as emissions_smoke
                                from company_industry_monitor_simulation_day_avg
                                where industry_id in $industry_limit_arr and company_id in $ids_contribution");
            // 查看是否包含晋能热电
            if (in_array(1, $id_arr_new)) {
                // 贡献企业包含晋能热电
                $contribution_emissions['so2']   = $data_simulate[0]['emissions_so2'] + $real_emissions_so2;
                $contribution_emissions['nox']   = $data_simulate[0]['emissions_nox'] + $real_emissions_nox;
                $contribution_emissions['smoke'] = $data_simulate[0]['emissions_smoke'];
            } else {
                // 不包含晋能热电
                $contribution_emissions['so2']   = $data_simulate[0]['emissions_so2'];
                $contribution_emissions['nox']   = $data_simulate[0]['emissions_nox'];
                $contribution_emissions['smoke'] = $data_simulate[0]['emissions_smoke'];
            }
        } else {
            $contribution_emissions = false;
        }
        # 全市贡献企业SO2,NOX,烟尘的排放总量
        $list[0]['contribution_emissions'] = $contribution_emissions ? $contribution_emissions['so2'] : '-';
        $list[1]['contribution_emissions'] = $contribution_emissions ? $contribution_emissions['nox'] : '-';
        $list[2]['contribution_emissions'] = $contribution_emissions ? $contribution_emissions['smoke'] : '-';

        # step3 全市贡献企业日均排放浓度 1.5.1算法（3）
        // 计算全市多天的运行浓度
        // 1.分子为行业多天排放量的和
        // 2.分母为 ∑(每家企业多天排放量的和/每家企业多天的运行浓度) ---行业运行浓度的分母
        $real_concentration = [];
        if (in_array(1, $id_arr_new)) {
            // 如果贡献企业中包含晋能热电
            $param['industry_id']                    = 1;
            $param['is_sulfur']                      = true;
            $real_concentration['concentration_so2'] = $commonService->getRealConcentration($param, 1)[0]['concentration']; //实时企业多天的脱硫运行浓度
            $param['is_sulfur']                      = false;
            $real_concentration['concentration_nox'] = $commonService->getRealConcentration($param, 1)[0]['concentration']; //实时企业多天的脱硝运行浓度
        }
        $data_simulate_company = Db::query("select sum(emissions_so2_total * $days) / avg(operation_concentration_so2) as result_concentration_so2, sum(emissions_nox_total * $days) / avg(operation_concentration_nox) as result_concentration_nox, industry_id, company_id, company_name
                                from company_industry_monitor_simulation_day_avg
                                where company_id in $ids_contribution and industry_id in $industry_limit_arr
                                group by company_id");
        $arr                   = [];
        foreach ($data_simulate_company as $kds => $vds) {
            $arr[$vds['company_id']]['concentration_so2'] = $vds['result_concentration_so2'];
            $arr[$vds['company_id']]['concentration_nox'] = $vds['result_concentration_nox'];
        }
        if (in_array(1, $id_arr_new)) {
            $arr[] = $real_concentration;
        }
        $arr                                       = array_values($arr);
        $concentration_so2_city                    = array_sum(array_column($arr, 'concentration_so2'));
        $concentration_nox_city                    = array_sum(array_column($arr, 'concentration_nox'));
        $list[0]['contribution_concentration_avg'] = $contribution_emissions['so2'] / $concentration_so2_city;
        $list[1]['contribution_concentration_avg'] = $contribution_emissions['nox'] / $concentration_nox_city;
        $list[2]['contribution_concentration_avg'] = '-';

        # step4 全市贡献企业日均排放量
        $list[0]['contribution_emissions_avg'] = $contribution_emissions ? round($contribution_emissions['so2'] / $days) : '-';
        $list[1]['contribution_emissions_avg'] = $contribution_emissions ? round($contribution_emissions['nox'] / $days) : '-';
        $list[2]['contribution_emissions_avg'] = $contribution_emissions ? round($contribution_emissions['smoke'] / $days) : '-';

        # step5 工业排放贡献度
        $industry_emissions_contribution = $this->getIndustryEmissionsContribution($param);
//        $list[0]['industry_emissions_contribution'] = $industry_emissions_contribution['so2_total'] > 0 ? $commonService->handleMathNum($industry_emissions_contribution['so2_total'] * 100) . '%' : $industry_emissions_contribution['so2_total'];
        $list[0]['industry_emissions_contribution'] = $industry_emissions_contribution['so2_total'] > 0 ? $commonService->contributionRound($industry_emissions_contribution['so2_total']) . '%' : $industry_emissions_contribution['so2_total'];
//        $list[1]['industry_emissions_contribution'] = $industry_emissions_contribution['no2_total'] > 0 ? $commonService->handleMathNum($industry_emissions_contribution['no2_total'] * 100) . '%' : $industry_emissions_contribution['no2_total'];
        $list[1]['industry_emissions_contribution'] = $industry_emissions_contribution['no2_total'] > 0 ? $commonService->contributionRound($industry_emissions_contribution['no2_total']) . '%' : $industry_emissions_contribution['no2_total'];
        $list[2]['industry_emissions_contribution'] = '-';

        #贡献企业排放总量扇形图
        $contribution_emissions_rose = [
            ['name' => 'SO2', 'value' => $contribution_emissions ? $contribution_emissions['so2'] : 0, 'types' => 'so2'],
            ['name' => 'NO2', 'value' => $contribution_emissions ? $contribution_emissions['nox'] : 0, 'types' => 'nox'],
            ['name' => '烟尘', 'value' => $contribution_emissions ? $contribution_emissions['smoke'] : 0, 'types' => 'smoke'],
        ];
        # 排放量单位转化为吨
        $list                        = $commonService->getRealData($list, 'emissions');
        $list                        = $commonService->getRealData($list, 'contribution_emissions');
        $list                        = $commonService->getRealData($list, 'contribution_emissions_avg');
        $contribution_emissions_rose = $commonService->getRealData($contribution_emissions_rose, 'value');
        foreach ($list as $ke => &$ve) {
            $ve['emissions']                      = $ve['emissions'] > 0 ? $ve['emissions'] . ' t' : $ve['emissions'];
            $ve['contribution_emissions']         = $ve['contribution_emissions'] > 0 ? $ve['contribution_emissions'] . ' t' : $ve['contribution_emissions'];
            $ve['contribution_emissions_avg']     = $ve['contribution_emissions_avg'] > 0 ? $ve['contribution_emissions_avg'] . ' t' : $ve['contribution_emissions_avg'];
            $ve['contribution_concentration_avg'] = $ve['contribution_concentration_avg'] > 0 ? round($ve['contribution_concentration_avg'], 1) . ' mg/m³' : $ve['contribution_concentration_avg'];
        }
        $arr = ['table' => $list, 'contribution_emissions' => $contribution_emissions_rose];
        return $arr;
    }

    /**
     * 获取工业排放贡献度
     * @author yy by 2019/5/21
     * @param $param
     * @return array
     * @throws \MongoDB\Driver\Exception\Exception
     */
    public function getIndustryEmissionsContribution($param = [])
    {
        $commonService     = new CommonService();
        $companyIdArr      = $commonService->getCompanyIdArr(0);
        $isIndustryId      = $commonService->getIndustryLimitId();
        $newTime           = $commonService->getMongoTime($param);
        $mongodb_huanxin   = new \MongoDB\Driver\Manager(Config::get('mongodb_url'));
        $document          = [
            'aggregate'    => Config::get('contribution_table_name'),
            'pipeline'     => [
                [
                    '$project' => [
                        'predict_time'        => 1,
                        'publish_time'        => 1,
                        'contribution_name'   => 1,
                        'company_id'          => 1,
                        'industry_id'         => 1,
                        'station_id'          => 1,
                        'region_id'           => 1,
                        'contribution_value'  => 1,  //  贡献度 TODO 增加贡献度、贡献值、浓度值字段的查询
                        'contribution_degree' => 1,  // 贡献值
                        'difference'          => ['$eq' => ['$publish_time', '$predict_time']]
                    ],
                ],
                [
                    '$match' => [
                        'difference'   => true,
                        'region_id'    => (int)$param['region_id'],
                        'station_id'   => Config::get('changzhi_id'),
                        'industry_id'  => ['$in' => $isIndustryId],//目前限制钢铁、水泥、电力、焦化行业
                        'company_id'   => ['$in' => $companyIdArr],//目前只查有正式名称的企业
//                        'contribution_name' => strtoupper($param['contribute_pollutant_name']),
                        'predict_time' => [
                            '$gte' => $newTime['start_time'],
                            '$lte' => $newTime['end_time'],
                        ],
                    ]
                ],
                [
                    '$group' => [
                        '_id'   => ['industry_id' => '$industry_id', 'company_id' => '$company_id', 'contribution_name' => '$contribution_name'],
                        'total' => ['$sum' => '$contribution_degree'] // 工业下各行业的各企业的各污染物对该站点的时间区间的贡献值和
                    ]
                ],
                [
                    '$sort' => [
                        "_id" => 1,
                    ]
                ]
            ],
            'allowDiskUse' => false,
        ];
        $command           = new \MongoDB\Driver\Command($document);
        $rows              = $mongodb_huanxin->executeCommand('huanxin', $command)->toArray();
        $contribution_data = json_decode(json_encode($rows, 320), true);
        # 时间区间的SO2,NO2浓度和
        $param['station_id']     = Config::get('changzhi_id');
        $param['pollutant_name'] = 'so2';
        $concentration_sum_so2   = $commonService->getConcentration($param);
        $param['pollutant_name'] = 'no2';
        $concentration_sum_no2   = $commonService->getConcentration($param);
        $concentration_data      = Db::query("select avg(so2) as so2_avg,avg(no2) as no2_avg
                                    from air_quality_station_aqi_realtime_day
                                    where region_id = ? and station_id = ? and DATE_FORMAT(publish_time, '%Y-%m-%d') between ? and ?
                                    ", [$param['region_id'], Config::get('changzhi_id'), $param['start_time'], $param['end_time']]);
        # 不同企业的SO2，NO2该时间区间的贡献度
//        $so2_total = 0;
//        $no2_total = 0;
        $no2_arr = [];
        $so2_arr = [];
        foreach ($contribution_data[0]['result'] as $k1 => $v1) {
            (strtolower($v1['_id']['contribution_name']) == 'no2') ? ($no2_arr[] = $v1['total']) : '';
            (strtolower($v1['_id']['contribution_name']) == 'so2') ? ($so2_arr[] = $v1['total']) : '';
            # 查询 *指定行业 *指定企业 *指定溯源物 对 *指定站点 的时间区间贡献度（同一家公司可能属于多个行业）
//            $industry[$v1['_id']['industry_id']][$v1['_id']['company_id']][$v1['_id']['contribution_name']]['degree'] = $v1['total'] / $concentration_data[0][strtolower($v1['_id']['contribution_name']) . '_avg'];
            # 同一污染物工业时间区间的贡献度 = 工业下各行业时间区间的贡献度和； 各行业时间区间的贡献度 = 各行业下各企业时间区间的贡献度和
//            (strtolower($v1['_id']['contribution_name']) == 'no2') ? ($no2_total += $v1['total'] / $concentration_data[0][strtolower($v1['_id']['contribution_name']) . '_avg']) : '';
//            (strtolower($v1['_id']['contribution_name']) == 'so2') ? ($so2_total += $v1['total'] / $concentration_data[0][strtolower($v1['_id']['contribution_name']) . '_avg']) : '';
        }
        $no2_sum   = array_sum($no2_arr); //no2贡献值和
        $so2_sum   = array_sum($so2_arr); //so2贡献值和
        $no2_total = $concentration_sum_no2 > 0 ? $no2_sum / $concentration_sum_no2 : '';
        $so2_total = $concentration_sum_so2 > 0 ? $so2_sum / $concentration_sum_so2 : '';
        # 工业的贡献度 = 属于工业的不同行业的不同公司贡献度相加
        $result = ['so2_total' => $so2_total, 'no2_total' => $no2_total];
        return $result;
    }

    /**
     * 获取指定行业或者全部行业下有贡献的企业ID集合
     * @author yy by 2019/5/21
     * @param array $param
     * @return array|string
     * @throws \MongoDB\Driver\Exception\Exception
     */
    public function getContributionCompanyIds($param = [])
    {
        $commonService      = new CommonService();
        $newTime            = $commonService->getMongoTime($param);
        $companyIdArr       = $commonService->getCompanyIdArr(0);
        $isIndustryId       = $commonService->getIndustryLimitId();
        $mongodb_huanxin    = new \MongoDB\Driver\Manager(Config::get('mongodb_url'));
        $document           = [
            'aggregate'    => Config::get('contribution_table_name'),
            'pipeline'     => [
                [
                    '$project' => [
                        'predict_time'       => 1,
                        'publish_time'       => 1,
                        'contribution_name'  => 1,
                        'company_id'         => 1,
                        'industry_id'        => 1,
                        'station_id'         => 1,
                        'region_id'          => 1,
                        'contribution_value' => 1,
                        'difference'         => ['$eq' => ['$publish_time', '$predict_time']]
                    ],
                ],
                [
                    '$match' => [
                        'difference'   => true,
                        'industry_id'  => ['$in' => $isIndustryId],
                        'company_id'   => ['$in' => $companyIdArr],
                        'region_id'    => (int)$param['region_id'],
                        'station_id'   => Config::get('changzhi_id'),
                        'predict_time' => [
                            '$gte' => $newTime['start_time'],
                            '$lte' => $newTime['end_time'],
                        ],
                    ]
                ],
            ],
            'allowDiskUse' => false,
        ];
        $command            = new \MongoDB\Driver\Command($document);
        $rows               = $mongodb_huanxin->executeCommand('huanxin', $command)->toArray();
        $contribution_trend = json_decode(json_encode($rows, 320), true);
        $ids_contribution   = [];
        # 企业不一定有贡献(全市排放量不一定等于贡献企业排放量, 贡献度必须大于0)
        foreach ($contribution_trend[0]['result'] as $k => $v) {
            if ($v['contribution_value'] > 0) {
                !in_array($v['company_id'], $ids_contribution) ? $ids_contribution[] = $v['company_id'] : '';
            }
        }
        sort($ids_contribution);
        $ids_contribution = '(' . implode(',', $ids_contribution) . ')';
        return $ids_contribution;
    }

    /**
     * 行业贡献企业排放总量占比(按行业分组)
     * @author yy by 2019/5/21
     * @param array $param
     * @return mixed
     * @throws \MongoDB\Driver\Exception\Exception
     */
    public function getIndustryCompanyEmissionRate($param = [])
    {
        if (strtolower($param['company_pollutant_name'] == 'so2')) {
            $emission_name = 'emissions_so2_total';
        } elseif (strtolower($param['company_pollutant_name'] == 'nox')) {
            $emission_name = 'emissions_nox_total';
        } else {
            $emission_name = 'emissions_smoke_total';
        }
        $list               = [];
        $commonService      = new CommonService();
        $industry_limit_arr = $commonService->getIndustryLimitIdmysql();
        $companyIdArr       = $commonService->getCompanyIdArr(1);
        $dayService         = new AirQualityStationAqiRealtimeDayService();
        $days               = $dayService->diffDays($param['start_time'], $param['end_time']);
        # 获取有贡献的企业ID集合
        $company_id_arr = $this->getContributionCompanyIds($param);
        if ($company_id_arr == '()') {
            $industry_info = Db::query("select id,name from basic_industry where id in $industry_limit_arr order by id asc");
            foreach ($industry_info as $k => $v) {
                $list[] = ['name' => $v['name'], 'value' => 0, 'industry_id' => $v['id']];
            }
        } else {
            # 模拟表(排除掉晋能长治热电有限公司)（不用判断时间）(SO2,NOX,烟尘)
            $data_simulate = Db::query("select sum($emission_name * $days) as emission, industry_id, industry_name
                                from company_industry_monitor_simulation_day_avg
                                where company_id in $companyIdArr and industry_id in $industry_limit_arr and company_id in $company_id_arr
                                group by industry_id");
            $id_arr        = trim(strtr(strtr($company_id_arr, '(', ' '), ')', ' '));
            $id_arr_new    = explode(',', $id_arr);
            if (in_array(1, $id_arr_new)) {
                // 贡献企业包含晋能热电
                $real_emission = $commonService->getRealCompanyEmission($param, 1); //实时企业多天的排放量
                foreach ($data_simulate as $ks => &$vs) {
                    if ($vs['industry_id'] == 1) {
                        $vs['emission'] += $real_emission[0]['emissions'];
                    }
                }
            }
            foreach ($data_simulate as $k => $v) {
                $list[] = ['name' => $v['industry_name'], 'value' => $v['emission'], 'industry_id' => $v['industry_id']];
            }
        }
        # 排放量单位转化为吨
        $commonService = new CommonService();
        $list          = $commonService->getRealData($list, 'value');
        return $list;
    }

    /**
     * 获取行业企业污染物排放量排名
     * @author yy by 2019/5/16
     * @param array $param
     * @return array
     */
    public function getEmissionRank($param = [])
    {
        # 指定行业指定污染物的企业排名
        $arr        = [];
        $jinneng_id = Config::get('company_jinneng');
        if (strtolower($param['company_pollutant_name']) == 'so2') {
            $emissions_name      = 'emissions_so2_avg';
            $emissions_name_real = 'emissions';
            $real_table          = 'company_industry_monitor_sulfur_day';
        } elseif (strtolower($param['company_pollutant_name']) == 'nox') {
            $emissions_name      = 'emissions_nox_avg';
            $emissions_name_real = 'emissions';
            $real_table          = 'company_industry_monitor_nitre_day';
        } elseif (strtolower($param['company_pollutant_name']) == 'smoke') {
            $emissions_name      = 'emissions_smoke_avg';
            $emissions_name_real = 'export_smoke_dust';
            $real_table          = 'company_industry_monitor_sulfur_day';
        }
        # 全市排放量
        $dayService     = new AirQualityStationAqiRealtimeDayService();
        $days           = $dayService->diffDays($param['start_time'], $param['end_time']);
        $hours_simulate = $days * 24;
        $hours_real     = Config::get('hours_real');
        $commonService  = new CommonService();
        $companyIdArr   = $commonService->getCompanyIdArr(1);
        # 模拟表(排除掉晋能长治热电有限公司)（不用判断时间）(SO2,NOX,烟尘)
        $data_simulate = Db::query("select sum($emissions_name * $hours_simulate) as emissions, company_name, company_id
                                from company_industry_monitor_simulation_day_avg
                                where company_id in $companyIdArr and industry_id  = ?
                                group by company_id", [$param['industry_id']]);
        # 脱硫表（SO2,烟尘) || 脱硝表（NOX)（查时间区间）
        $data_real = Db::query("select sum($emissions_name_real) as emissions, company_name, company_id
                                from $real_table
                                where power = 1 and industry_id = ? and DATE_FORMAT(publish_time, '%Y-%m-%d') between ? and ?
                                group by company_id", [$param['industry_id'], $param['start_time'], $param['end_time']]);
        $list      = array_merge($data_simulate, $data_real);// 按企业查模拟表和脱硫脱硝表没有交集(晋能热电和其他企业),可以直接合并
        # 根据排放量高低进行排序
        $rule = array_column($list, 'emissions');//排放量
        array_multisort($rule, SORT_DESC, $list);
        $arr['date']    = array_column($list, 'company_name');
        $arr['data'][0] = array_column($list, 'emissions');
        $arr['id']      = array_column($list, 'company_id');

        # 企业简称获取
        $company = Db::query("select id,short_name,name from basic_company");
        $new     = [];
        foreach ($company as $k15 => $v15) {
            $new[$v15['id']] = $v15['short_name'] ?: $v15['name'];
        }
        for ($m = 0; $m < count($arr['id']); $m++) {
            $arr['date'][$m] = $new[$arr['id'][$m]];
        }
        # 排放量单位转化为吨
        $arr['data'][0] = $commonService->getRealData($arr['data'][0]);
        return $arr;
    }

    /**
     * 行业企业贡献度排名
     * @author yy by 2019/5/22
     * @param array $param
     * @return array
     * @throws \MongoDB\Driver\Exception\Exception
     */
    public function getContributionRank($param = [])
    {
        $list              = [];
        $commonService     = new CommonService();
        $companyIdArr      = $commonService->getCompanyIdArr(0);
        $newTime           = $commonService->getMongoTime($param);
        $mongodb_huanxin   = new \MongoDB\Driver\Manager(Config::get('mongodb_url'));
        $document          = [
            'aggregate'    => Config::get('contribution_table_name'),
            'pipeline'     => [
                [
                    '$project' => [
                        'predict_time'        => 1,
                        'publish_time'        => 1,
                        'contribution_name'   => 1,
                        'company_id'          => 1,
                        'industry_id'         => 1,
                        'station_id'          => 1,
                        'region_id'           => 1,
                        'contribution_value'  => 1, //贡献度
                        'contribution_degree' => 1, //贡献值
                        'difference'          => ['$eq' => ['$publish_time', '$predict_time']]
                    ],
                ],
                [
                    '$match' => [
                        'difference'        => true,
                        'region_id'         => (int)$param['region_id'],
                        'station_id'        => Config::get('changzhi_id'),//长治市id
                        'industry_id'       => (int)$param['industry_id'],
                        'company_id'        => ['$in' => $companyIdArr],
                        'contribution_name' => strtoupper($param['contribute_pollutant_name']),
                        'predict_time'      => [
                            '$gte' => $newTime['start_time'],
                            '$lte' => $newTime['end_time'],
                        ],
                    ]
                ],
                [
                    '$group' => [
                        '_id'   => ['company_id' => '$company_id'],
                        'total' => ['$sum' => '$contribution_degree'] // TODO 同一企业时间区间贡献值
                    ]
                ],
                [
                    '$sort' => [
                        'total' => -1,
                    ]
                ]
            ],
            'allowDiskUse' => true,
        ];
        $command           = new \MongoDB\Driver\Command($document);
        $rows              = $mongodb_huanxin->executeCommand('huanxin', $command)->toArray();
        $contribution_data = json_decode(json_encode($rows, 320), true);

        if (count($contribution_data[0]['result']) > 0) {
            # 指定污染物的时间区间有效浓度和
            $param['pollutant_name'] = str_replace('.', '', strtolower($param['contribute_pollutant_name']));
            $param['station_id']     = Config::get('changzhi_id');
            $concentration_sum       = $commonService->getConcentration($param);

            # 时间区间的SO2,NO2浓度
//            $need               = strtolower($param['contribute_pollutant_name']);
//            $concentration_need = Db::query("select avg($need) as avg_value
//                                    from air_quality_station_aqi_realtime_day
//                                    where region_id = ? and station_id = ? and DATE_FORMAT(publish_time, '%Y-%m-%d') between ? and ?
//                                    ", [$param['region_id'], Config::get('changzhi_id'), $param['start_time'], $param['end_time']]);
//            $arr                = [];
            foreach ($contribution_data[0]['result'] as $k => $v) {
                $list['id'][] = $v['_id']['company_id'];
//                $list['data'][0][] = round($v['total'] / $concentration_need[0]['avg_value'] * 100, 2); //返给前端是直接就是百分比
//                $list['data'][0][] = $concentration_sum > 0 ? $v['total'] / $concentration_sum * 100 : ''; //返给前端是直接就是百分比
                $list['data'][0][] = $concentration_sum > 0 ? $commonService->contributionRound($v['total'] / $concentration_sum) : ''; //返给前端是直接就是百分比
            }
            # 根据贡献度value进行从高到低排序
            array_multisort($list['data'][0], SORT_DESC, $list['id']);
            # 查询公司名称
            $company_id_arr = '(' . implode(',', $list['id']) . ')';
            $company        = Db::query("select id,short_name,name from basic_company where id in $company_id_arr");
            $company        = array_column($company, null, 'id');
            for ($i = 0; $i < count($list['id']); $i++) {
                $list['date'][] = $company[$list['id'][$i]]['short_name'] ?: $company[$list['id'][$i]]['name'];
            }
        } else {
            $list = ['id' => [], 'data' => [[]], 'date' => []];
        }

        return $list;
    }

    /**
     * 首要污染物趋势图
     * @author yy by 2019/5/16
     * @param array $param
     * @return mixed
     */
    public function getPrimaryPollutantTrend($param = [])
    {
        $list          = [];
        $commonService = new CommonService();
        $list['date']  = $commonService->getDate($param['start_time'], $param['end_time']);
        $pollutant     = strtolower($param['primary_pollutant_name']);
        $data          = Db::query("select $pollutant as pollutant_value,DATE_FORMAT(publish_time, '%Y-%m-%d') as date, avg($pollutant) as average
                              from air_quality_station_aqi_realtime_day
                              where region_id = ? and station_id = ? and DATE_FORMAT(publish_time, '%Y-%m-%d') between ? and ?
                              group by publish_time", [$param['region_id'], $param['station_id'], $param['start_time'], $param['end_time']]);
        $num           = count($data);
        if ($num > 0) {
            $arr['date']    = array_column($data, 'date');
            $arr['data'][0] = array_column($data, 'pollutant_value');
            # 比较差集
            $different     = array_values(array_diff($list['date'], $arr['date']));
            $different_num = count($different);
            if ($different_num > 0) {
                for ($i = 0; $i < $different_num; $i++) {
                    $arr['date'][]    = $different[$i];
                    $arr['data'][0][] = '';
                }
            }
        } else {
            $arr['date'] = $list['date'];
            for ($i = 0; $i < count($arr['date']); $i++) {
                $arr['data'][0][$i] = '';
            }
        }
        # 依据publish_time排序
        array_multisort($arr['date'], $arr['data'][0]);
        for ($m = 0; $m < count($arr['date']); $m++) {
            $arr['date'][$m]    = date('m/d', strtotime($arr['date'][$m]));
            $arr['data'][0][$m] = ($arr['data'][0][$m] === '') ? '' : round($arr['data'][0][$m]); //考虑到有实际值为0的情况
        }
        # 站点平均值
        $arr['average_station'] = ($num > 0) ? round(array_sum(array_column($data, 'average')) / $num) : '';
        return $arr;
    }

    /**
     * 行业排放趋势图及平均值（只能查全市，不用判断station_id和region_id）
     * @author yy by 2019/5/24
     * @param array $param
     * @return array
     */
    public function getIndustryEmissionTrend($param = [])
    {
        $list       = [];
        $jinneng_id = Config::get('company_jinneng');
        if (strtolower($param['company_pollutant_name']) == 'so2') {
            $emissions_name      = 'emissions_so2_avg';
            $emissions_name_real = 'emissions';
            $real_table          = 'company_industry_monitor_sulfur_day';
        } elseif (strtolower($param['company_pollutant_name']) == 'nox') {
            $emissions_name      = 'emissions_nox_avg';
            $emissions_name_real = 'emissions';
            $real_table          = 'company_industry_monitor_nitre_day';
        } elseif (strtolower($param['company_pollutant_name']) == 'smoke') {
            $emissions_name      = 'emissions_smoke_avg';
            $emissions_name_real = 'export_smoke_dust';
            $real_table          = 'company_industry_monitor_sulfur_day';
        }
        $hours_real    = Config::get('hours_real');
        $commonService = new CommonService();
        $companyIdArr  = $commonService->getCompanyIdArr(1);
        # SO2||NOX||烟尘 的排放量（模拟数据）每一天都是相同模拟数据 20190530改为求和
        $data_simulate = Db::query("select sum($emissions_name * $hours_real) as emissions,industry_id
                                from company_industry_monitor_simulation_day_avg
                                where company_id in $companyIdArr and industry_id  = ?
                                ", [$param['industry_id']]);
        # 晋能热电脱硫或脱硝-排放量
        $data_real = Db::query("select sum($emissions_name_real) as emissions,industry_id, DATE_FORMAT(publish_time, '%Y-%m-%d') as date
                                from $real_table
                                where power = 1 and industry_id = ? and DATE_FORMAT(publish_time, '%Y-%m-%d') between ? and ?
                                group by publish_time", [$param['industry_id'], $param['start_time'], $param['end_time']]);
        # 目前是电力行业查两个表，其他行业查一个表
        $date_all = $commonService->getDate($param['start_time'], $param['end_time']);
        # 比较差集
        if (count($data_real) > 0) {
            foreach ($data_real as $k => &$v) {
                foreach ($data_simulate as $k2 => $v2) {
                    if ($v2['industry_id'] == $v['industry_id']) {
                        $v['emissions'] += $v2['emissions'];
                    }
                }
            }
            $average_station = array_sum(array_column($data_real, 'emissions')) / count($data_real);
            $list['date']    = array_column($data_real, 'date');
            $list['data'][0] = array_column($data_real, 'emissions');
            $different       = array_values(array_diff($date_all, $list['date']));
            $different_num   = count($different);
            if ($different_num > 0) {
                for ($i = 0; $i < $different_num; $i++) {
                    $list['date'][]    = $different[$i];
                    $list['data'][0][] = $data_simulate[0]['emissions'];
                }
            }
        } else {
            # 如果没有脱硫脱硝数据，那么所有天都只计算指定行业的模拟数据
            $average_station = $data_simulate[0]['emissions'];
            $list['date']    = $date_all;
            for ($i = 0; $i < count($list['date']); $i++) {
                $list['data'][0][] = $data_simulate[0]['emissions'];
            }
        }
        # 按照publish_time排序
        array_multisort($list['date'], $list['data'][0]);
        for ($m = 0; $m < count($list['date']); $m++) {
            $list['date'][$m] = date('m/d', strtotime($list['date'][$m]));
        }
        # 排放量单位转化为吨
        $commonService   = new CommonService();
        $list['data'][0] = $commonService->getRealData($list['data'][0]);
        $average_station = ($average_station > 0) ? round($average_station / Config::get('emission_denominator'), 2) : $average_station;
        for ($i = 0; $i < count($list['data'][0]); $i++) {
            $list['data'][1][$i] = $average_station;
        }
        return $list;
    }

    /**
     * 获取行业贡献度趋势图
     * @author yy by 2019/5/23
     * @param array $param
     * @return array
     * @throws \MongoDB\Driver\Exception\Exception
     */
    public function getIndustryContributeTrend($param = [])
    {
        $list              = [];
        $commonService     = new CommonService();
        $newTime           = $commonService->getMongoTime($param);
        $mongodb_huanxin   = new \MongoDB\Driver\Manager(Config::get('mongodb_url'));
        $document          = [
            'aggregate'    => Config::get('contribution_table_name'),
            'pipeline'     => [
                [
                    '$project' => [
                        'predict_time'        => 1,
                        'publish_time'        => 1,
                        'contribution_name'   => 1,
                        'company_id'          => 1,
                        'industry_id'         => 1,
                        'station_id'          => 1,
                        'region_id'           => 1,
                        'contribution_value'  => 1, //贡献度
                        'contribution_degree' => 1, //贡献值
                        'concentration'       => 1,
                        'difference'          => ['$eq' => ['$publish_time', '$predict_time']]
                    ],
                ],
                [
                    '$match' => [
                        'difference'        => true,
                        'region_id'         => (int)$param['region_id'],
                        'station_id'        => (int)$param['station_id'],
                        'industry_id'       => (int)$param['industry_id'],
                        'contribution_name' => strtoupper($param['contribute_pollutant_name']),
                        'predict_time'      => [
                            '$gte' => $newTime['start_time'],
                            '$lte' => $newTime['end_time'],
                        ],
                    ]
                ],
                [
                    '$group' => [
                        '_id'               => ['publish_time' => '$publish_time'],
                        'total'             => ['$sum' => '$contribution_degree'], // TODO 指定行业一天的贡献值 = 这个行业下不同企业同一天贡献值 相加
                        'concentration_sum' => ['$avg' => '$concentration'] //该站点这一天的浓度
                    ]
                ],
                [
                    '$sort' => [
                        '_id' => 1,
                    ]
                ]
            ],
            'allowDiskUse' => true,
        ];
        $command           = new \MongoDB\Driver\Command($document);
        $rows              = $mongodb_huanxin->executeCommand('huanxin', $command)->toArray();
        $contribution_data = json_decode(json_encode($rows, 320), true);
        $date_all          = $commonService->getDate($param['start_time'], $param['end_time']);
        $num               = count($contribution_data[0]['result']);
        $dayService        = new AirQualityStationAqiRealtimeDayService();
        $days              = $dayService->diffDays($param['start_time'], $param['end_time']);
        if ($num > 0) {
            # 站点平均值
            foreach ($contribution_data[0]['result'] as $k => $v) {
                $list['date'][]    = date('Y-m-d', strtotime($v['_id']['publish_time']));
                $list['data'][0][] = $v['concentration_sum'] > 0 ? $commonService->contributionRound($v['total'] / $v['concentration_sum']) : '';
            }
//            $average_station = array_sum($list['data'][0]) / $days * 100; //返给前端是百分比
            $average_station = $commonService->contributionRound(array_sum($list['data'][0]) / ($days * 100)); //返给前端是百分比
            # 比较差集
            $different     = array_values(array_diff($date_all, $list['date']));
            $different_num = count($different);
            if ($different_num > 0) {
                for ($i = 0; $i < $different_num; $i++) {
                    $list['date'][]    = $different[$i];
                    $list['data'][0][] = '';
                }
            }
        } else {
            $list['date'] = $date_all;
            # 站点平均值
            $average_station = '';
            for ($i = 0; $i < count($list['date']); $i++) {
                $list['data'][0][$i] = '';
            }
        }
        # 依据publish_time排序
        array_multisort($list['date'], $list['data'][0]);
        for ($m = 0; $m < count($list['date']); $m++) {
            $list['date'][$m] = date('m/d', strtotime($list['date'][$m]));
//            $list['data'][0][$m] = $list['data'][0][$m] >= 0 ? $list['data'][0][$m] * 100 : '';
            $list['data'][0][$m] = $list['data'][0][$m] >= 0 ? $list['data'][0][$m] : '';
        }
        for ($i = 0; $i < count($list['data'][0]); $i++) {
            $list['data'][1][$i] = $average_station;
        }
        return $list;
    }

    /**
     *  企业排放趋势图及平均值（只能查全市，不用判断station_id和region_id）
     * @author yy by 2019/5/17
     * @param array $param
     * @return mixed
     */
    public function getCompanyEmissionTrend($param = [])
    {
        $list = [];
        if (strtolower($param['company_pollutant_name']) == 'so2') {
            $emissions_name      = 'emissions_so2_avg';
            $emissions_name_real = 'emissions';
            $real_table          = 'company_industry_monitor_sulfur_day';
        } elseif (strtolower($param['company_pollutant_name']) == 'nox') {
            $emissions_name      = 'emissions_nox_avg';
            $emissions_name_real = 'emissions';
            $real_table          = 'company_industry_monitor_nitre_day';
        } elseif (strtolower($param['company_pollutant_name']) == 'smoke') {
            $emissions_name      = 'emissions_smoke_avg';
            $emissions_name_real = 'export_smoke_dust';
            $real_table          = 'company_industry_monitor_sulfur_day';
        }
        # 目前是晋能热电查脱硫脱硝表，其他企业查模拟表
        $commonService = new CommonService();
        $date_all      = $commonService->getDate($param['start_time'], $param['end_time']);
        $companyIdArr  = $commonService->getCompanyIdArr(1);
        $hours_real    = Config::get('hours_real');
        if ($param['company_id'] == Config::get('company_jinneng')) { //晋能热电
            # 脱硫表（SO2,烟尘) || 脱硝表（NOX)（查时间区间） 20190530改为求和
            $data_real = Db::query("select sum($emissions_name_real) as emissions, company_name, company_id, DATE_FORMAT(publish_time, '%Y-%m-%d') as date
                                from $real_table
                                where power = 1 and industry_id = ? and company_id = ? and DATE_FORMAT(publish_time, '%Y-%m-%d') between ? and ?
                                group by publish_time", [$param['industry_id'], $param['company_id'], $param['start_time'], $param['end_time']]);
            if (count($data_real) > 0) {
                # 比较差集
                $average_station = array_sum(array_column($data_real, 'emissions')) / count($data_real);
                $list['date']    = array_column($data_real, 'date');
                $list['data'][0] = array_column($data_real, 'emissions');
                $different       = array_values(array_diff($date_all, $list['date']));
                $different_num   = count($different);
                if ($different_num > 0) {
                    for ($i = 0; $i < $different_num; $i++) {
                        $list['date'][]    = $different[$i];
                        $list['data'][0][] = '';
                    }
                }
            } else {
                $list['date']    = $date_all;
                $average_station = '';
                for ($i = 0; $i < count($date_all); $i++) {
                    $list['data'][0][$i] = '';
                }
            }
        } else {
            # 模拟表(排除掉晋能长治热电有限公司)（不用判断时间）(SO2,NOX,烟尘)
            $data_simulate   = Db::query("select sum($emissions_name * $hours_real) as emissions, company_name, company_id
                                from company_industry_monitor_simulation_day_avg
                                where company_id in $companyIdArr and industry_id  = ? and company_id = ?
                                ", [$param['industry_id'], $param['company_id']]);
            $list['date']    = $date_all;
            $average_station = $data_simulate[0]['emissions'];
            for ($i = 0; $i < count($date_all); $i++) {
                $list['data'][0][$i] = $data_simulate[0]['emissions'];
            }
        }
        # 按照publish_time排序
        array_multisort($list['date'], $list['data'][0]);
        for ($m = 0; $m < count($list['date']); $m++) {
            $list['date'][$m] = date('m/d', strtotime($list['date'][$m]));
        }
        # 排放量单位转化为吨
        $commonService   = new CommonService();
        $average_station = ($average_station > 0) ? round($average_station / Config::get('emission_denominator'), 2) : $average_station;
        $list['data'][0] = $commonService->getRealData($list['data'][0]);
        for ($i = 0; $i < count($list['data'][0]); $i++) {
            $list['data'][1][$i] = $average_station;
        }
        return $list;
    }

    /**
     * 企业贡献度趋势图
     * @author yy by 2019/5/24
     * @param array $param
     * @return array
     * @throws \MongoDB\Driver\Exception\Exception
     */
    public function getCompanyContributeTrend($param = [])
    {
        $list              = [];
        $commonService     = new CommonService();
        $newTime           = $commonService->getMongoTime($param);
        $mongodb_huanxin   = new \MongoDB\Driver\Manager(Config::get('mongodb_url'));
        $document          = [
            'aggregate'    => Config::get('contribution_table_name'),
            'pipeline'     => [
                [
                    '$project' => [
                        'predict_time'        => 1,
                        'publish_time'        => 1,
                        'contribution_name'   => 1,
                        'company_id'          => 1,
                        'industry_id'         => 1,
                        'station_id'          => 1,
                        'region_id'           => 1,
                        'contribution_value'  => 1,//贡献度
                        'contribution_degree' => 1,//贡献值
                        'difference'          => ['$eq' => ['$publish_time', '$predict_time']]
                    ],
                ],
                [
                    '$match' => [
                        'difference'        => true,
                        'region_id'         => (int)$param['region_id'],
                        'station_id'        => (int)$param['station_id'],
                        'industry_id'       => (int)$param['industry_id'],
                        'company_id'        => (int)$param['company_id'],
                        'contribution_name' => strtoupper($param['contribute_pollutant_name']),
                        'predict_time'      => [
                            '$gte' => $newTime['start_time'],
                            '$lte' => $newTime['end_time'],
                        ],
                    ]
                ],
//                [
//                    '$group' => [
//                        '_id'   => ['publish_time' => '$publish_time'],
//                        'total' => ['$sum' => '$contribution_value'] // TODO 指定行业指定企业同一天贡献值 avg和sum都一样
//                    ]
//                ],
//                [
//                    '$sort' => [
//                        '_id' => 1,
//                    ]
//                ]
            ],
            'allowDiskUse' => true,
        ];
        $command           = new \MongoDB\Driver\Command($document);
        $rows              = $mongodb_huanxin->executeCommand('huanxin', $command)->toArray();
        $contribution_data = json_decode(json_encode($rows, 320), true);
        $date_all          = $commonService->getDate($param['start_time'], $param['end_time']);
        $dayService        = new AirQualityStationAqiRealtimeDayService();
        $days              = $dayService->diffDays($param['start_time'], $param['end_time']);
        if (count($contribution_data[0]['result']) > 0) {
            # 比较差集
            $average_station = $commonService->contributionRound(array_sum(array_column($contribution_data[0]['result'], 'contribution_value')) / $days);
            $list['date']    = array_column($contribution_data[0]['result'], 'publish_time');
            foreach ($list['date'] as $k => &$v) {
                $v = date('Y-m-d', strtotime($v));
            }
            $list['data'][0] = array_column($contribution_data[0]['result'], 'contribution_value');
            $different       = array_values(array_diff($date_all, $list['date']));
            $different_num   = count($different);
            if ($different_num > 0) {
                for ($i = 0; $i < $different_num; $i++) {
                    $list['date'][]    = $different[$i];
                    $list['data'][0][] = '';
                }
            }
        } else {
            $list['date']    = $date_all;
            $average_station = '';
            for ($i = 0; $i < count($date_all); $i++) {
                $list['data'][0][$i] = '';
            }
        }
        # 按照publish_time排序
        array_multisort($list['date'], $list['data'][0]);
        for ($m = 0; $m < count($list['date']); $m++) {
            $list['date'][$m] = date('m/d', strtotime($list['date'][$m]));
//            $list['data'][0][$m] = ($list['data'][0][$m] > 0) ? $list['data'][0][$m] * 100 : $list['data'][0][$m]; //返给前端是百分比
            $list['data'][0][$m] = ($list['data'][0][$m] > 0) ? $commonService->contributionRound($list['data'][0][$m]) : $list['data'][0][$m]; //返给前端是百分比
        }
        for ($i = 0; $i < count($list['data'][0]); $i++) {
            $list['data'][1][$i] = $average_station;
        }
        return $list;
    }

}